Skip to content

Add support for UnsafeRawBufferPointer to DispatchData #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 10, 2017
Merged

Add support for UnsafeRawBufferPointer to DispatchData #230

merged 2 commits into from
Mar 10, 2017

Conversation

ktopley-apple
Copy link
Contributor

@ktopley-apple ktopley-apple commented Mar 9, 2017

(Radar 30699743)
rdar://problem/30699743

@ktopley-apple
Copy link
Contributor Author

@swift-ci please test

/// Initialize a `Data` without copying the bytes.
///
/// - parameter bytes: A buffer pointer containing the data.
/// - parameter deallocator: Specifies the mechanism to free the indicated buffer.
@available(swift, deprecated: 4, message: "Use init(bytes: UnsafeRawBufferPointer, deallocater: Deallocator) instead")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to say "bytesNoCopy"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good catch.

///
/// - parameter pointer: A pointer to the buffer you wish to copy the bytes into.
/// - parameter count: The number of bytes to copy.
/// - warning: This method does not verify that the contents at pointer have enough space to hold `count` bytes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it should do that, now that you're passing a buffer pointer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stepping back, does it also make sense to default the count to the entire data, or would someone just not write that? How do I do an offset?

Stepping back even further…is this a necessary API at all? Normally in Swift we'd write this as

buffer.append(data[0..<count])

and if that's not going to be as efficient we should try to figure out what to do there. cc @airspeedswift

Copy link
Contributor Author

@ktopley-apple ktopley-apple Mar 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it should do that, now that you're passing a buffer pointer?

Yes, I think it should probably copy min(buffer count, given count) [and that behavior will be documented].

Regarding the other comments, this change is intended to be the minimal change to allow us to support UnsafeRawBufferPointer. We want to keep the API in line with that of Foundation's Data and to that end I don't want to add anything new until Foundation has agreed to do the same. There will be more work in this area in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you know if it copied the whole thing? I'd prefer to assert, so that clients are encouraged to check the length beforehand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to duplicate the role of UnsafeMutableRawBufferPointer.initializeMemory<S: Sequence>(as: S.Iterator.Element.Type, from source: S). There shouldn't be a performance penalty if we do the _copyContents trick (which it looks like UnsafeMutableRawBufferPointer isn't taking advantage of, but should). We should probably revisit this. cc @phausler

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to assert, so that clients are encouraged to check the length beforehand.

That seems like a good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stepping back even further…is this a necessary API at all? Normally in Swift we'd write this as

buffer.append(data[0..<count])

This kind of thing is not likely to be efficient because the DispatchData could be composed of several discontiguous regions which would have to first be flattened (by copy) before being sliced and copied again (unless I am misunderstanding how that statement would work). The existing copy code handles the discontinuity without additional copies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slicing doesn't immediately flatten, but append might go byte-by-byte by default. Ben would know more than me, though.

@karwa
Copy link

karwa commented Mar 9, 2017

What about withUnsafeBytes and enumerateBytes? Seems they should also both be using UnsafeRawBufferPointer

@ktopley-apple
Copy link
Contributor Author

ktopley-apple commented Mar 9, 2017

What about withUnsafeBytes and enumerateBytes? Seems they should also both be using UnsafeRawBufferPointer

It's a deliberate choice to not add support for UnsafeRawBufferPointer to the enumerateBytes and withUnsafeBytes methods at this time. Adding a variant of either method that accepts an UnsafeRawBufferPointer argument creates an ambiguity at the call site when writing the closure, unless the user explicitly writes the type of the buffer argument. In a later release, we plan to add better APIs to both the DispatchData and the Foundation Data classes.

@shahmishal
Copy link
Member

@swift-ci please test

@ktopley-apple
Copy link
Contributor Author

Updated for review comments. The API-related comments are deferred until later, pending further discussion with Foundation.

@ktopley-apple
Copy link
Contributor Author

@swift-ci please test

@ktopley-apple ktopley-apple merged commit 1cc64e1 into swiftlang:master Mar 10, 2017
@phausler
Copy link

shouldnt you also fix this too?
public func copyBytes(to buffer: UnsafeMutableBufferPointer, from range: CountableRange? = nil) -> Int

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants